<template>
  <div class="my-editor" @click="handleClick">
    <Toolbar
      style="border-bottom: 1px solid #ccc"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
    />
    <Editor
      style="height: 100%; overflow-y: hidden"
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      @onCreated="handleCreated"
    />
  </div>
</template>

<script lang="ts" setup>
import { onBeforeUnmount, ref, shallowRef } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import type { IEditorConfig } from '@wangeditor/editor'
import { watchThrottled } from '@vueuse/core'
type InsertFnType = (url: string, alt: string, href: string) => void

// ====== emit
const emit = defineEmits(['getVal'])

// ====== data
const editorRef = shallowRef() // 编辑器实例，必须用 shallowRef
const valueHtml = ref('') // 内容 HTML
const mode = ref('simple')

const toolbarConfig = {
  excludeKeys: ['fullScreen']
}
const editorConfig: Partial<IEditorConfig> = {
  placeholder: '请输入内容...',
  MENU_CONF: {
    uploadImage: {
      async customUpload(file: File, insertFn: InsertFnType) {
        // 自己实现上传，file 即选中的文件，通过服务器返回数据得到图片 url alt href，最后插入图片
        // const formData = new FormData()
        // formData.append('goods_img', file)
        // uploadFile(formData)
        //   .then((res: any) => {
        //     const { code, result } = res
        //     if (code && code == '0') {
        //       insertFn(result, '', '')
        //     }
        //   })
        //   .catch((err: any) => {
        //     console.log('上传失败：', err)
        //   })
      }
    }
  }
}

// ====== watch
watchThrottled(
  valueHtml,
  newVal => {
    emit('getVal', newVal)
  },
  { throttle: 500 }
)

// ====== methods
const handleCreated = (editor: any) => {
  editorRef.value = editor // 记录 editor 实例，重要！
}
const setVal = (payload: any) => {
  var reg = /<(p)[^>]*>/g
  if (reg.test(payload)) {
    valueHtml.value = payload
  } else {
    valueHtml.value = `<p>${payload}</p>`
  }
}
const handleClick = () => {
  if (editorRef.value) {
    editorRef.value?.focus() // focus 到末尾
  }
}

// ====== lifecycle
// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

// ====== expose
defineExpose({
  valueHtml,
  setVal
})
</script>

<style lang="less" scoped>
.my-editor {
  width: 100%;

  :deep(.w-e-scroll) {
    min-height: 500px;
    height: 500px;
    font-size: 18px;
  }
}
</style>
